package com.wpx.log.spring.boot.autoconfigure;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.Ordered;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.web.context.request.RequestContextListener;

import com.wpx.log.core.LogContext;
import com.wpx.log.core.aspect.DoHandler;
import com.wpx.log.core.aspect.LogAspect;
import com.wpx.log.core.filter.BodyReaderFilter;

@Configuration
@ComponentScan({"com.wpx.log.core"})
@EnableConfigurationProperties(LogProperties.class)
public class WpxLogAutoConfiguration implements InitializingBean{

	private static final Logger logger = LoggerFactory.getLogger(WpxLogAutoConfiguration.class);

	@Bean
	public LogContext logContext(LogProperties properties) {
		LogContext logContext = new LogContext(properties);
		return logContext;
	}

	@Bean
	public DoHandler doHandler() {
		return new DoHandler();
	}

	@Bean
	public LogAspect logAspect() {
		return new LogAspect();
	}


	@Bean
	public EvaluationContext beanFactoryEvaluationContext(ApplicationContext applicationContext ) {
		ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext)applicationContext;
		ConfigurableListableBeanFactory beanFactory = configurableApplicationContext.getBeanFactory();
		StandardEvaluationContext context = new StandardEvaluationContext();
		context.setBeanResolver(new BeanFactoryResolver(beanFactory));
		return context;
	}

	@Bean
	@ConditionalOnMissingBean(RequestContextListener.class)
	public RequestContextListener requestContextListener(){
	    return new RequestContextListener();
	} 
	
	@Bean 
	public FilterRegistrationBean bodyReaderFilter(){
	    FilterRegistrationBean registrationBean =  
	        new FilterRegistrationBean(); 
	    registrationBean.setFilter(new BodyReaderFilter());  
	    registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
	    registrationBean.addUrlPatterns("/*"); 
	    return registrationBean; 
	}

	
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("                               .__                  \r\n"
				+ "__  _  __________  ___         |  |   ____   ____  			\r\n"
				+ "\\ \\/ \\/ |____ \\  \\/  /  ______ |  |  /  _ \\ / ___\\ 	\r\n"
				+ " \\     /|  |_> >    <  /_____/ |  |_(  <_> ) /_/  >			\r\n"
				+ "  \\/\\_/ |   __/__/\\_ \\         |____/\\____/\\___  / 	\r\n"
				+ "        |__|        \\/                    /_____/  			");
		
		System.out.println(" :: wpx-log ::       (v2.0.4)");
		System.out.println();
	}

}
